<template>
  <div ref="mapContainer" class="map-gpx"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
import Map from 'ol/Map'
import View from 'ol/View'
import { fromLonLat } from 'ol/proj'
import TileLayer from 'ol/layer/Tile'
import XYZ from 'ol/source/XYZ'
import VectorLayer from 'ol/layer/Vector'
import VectorSource from 'ol/source/Vector'
import GPX from 'ol/format/GPX'
import Style from 'ol/style/Style'
import Stroke from 'ol/style/Stroke'
import CircleStyle from 'ol/style/Circle'
import Fill from 'ol/style/Fill'
import { Point, LineString, MultiLineString } from 'ol/geom'

const mapContainer = ref<HTMLDivElement | null>(null)
let map: Map | null = null
let gpxLayer: VectorLayer<VectorSource> | null = null

onMounted(() => {
  // 1. 创建高德地图底图图层
  const gaodeLayer = new TileLayer({
    source: new XYZ({
      url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
    })
  })

  // 2. 创建 GPX 数据源，加载轨迹文件
  const vectorSource = new VectorSource({
    url: '/data/gpx/fells_loop.gpx', // 注意：需放在 public 目录下
    format: new GPX()
  })

  // 3. 定义轨迹线样式（红色线）
  const lineStyle = new Style({
    stroke: new Stroke({
      color: '#ff3300',
      width: 4
    })
  })
  // 4. 定义 Waypoint 样式（黄色圆点）
  const pointStyle = new Style({
    image: new CircleStyle({
      radius: 7,
      fill: new Fill({ color: 'yellow' }),
      stroke: new Stroke({ color: '#ffcc00', width: 2 })
    })
  })

  // 5. 样式函数：根据要素类型区分样式
  function styleFunction(feature: any) {
    const geom = feature.getGeometry()
    if (geom instanceof Point) {
      return pointStyle // Waypoint
    }
    if (geom instanceof LineString || geom instanceof MultiLineString) {
      return lineStyle // 轨迹线
    }
    return undefined // 不返回null，避免类型错误
  }

  // 6. 创建 GPX 图层，应用样式函数
  gpxLayer = new VectorLayer({
    source: vectorSource,
    style: styleFunction
  })

  // 7. 初始化地图，叠加底图和GPX图层
  map = new Map({
    target: mapContainer.value as HTMLDivElement,
    layers: [gaodeLayer, gpxLayer],
    view: new View({
      center: fromLonLat([-3.0886, 54.5418]), // 初始中心（英国湖区）
      zoom: 13,
      minZoom: 3,
      maxZoom: 18
    })
  })

  // 8. GPX数据加载完成后自动定位到轨迹范围
  vectorSource.on('change', () => {
    if (vectorSource.getState() === 'ready') {
      const extent = vectorSource.getExtent()
      if (extent && map) {
        map.getView().fit(extent, { padding: [40, 40, 40, 40], maxZoom: 16 })
      }
    }
  })
})

onBeforeUnmount(() => {
  if (map) {
    map.setTarget(undefined);
    map = null;
  }
  if (gpxLayer) {
    gpxLayer = null;
  }
})
</script>

<script lang="ts">
export default {
  name: 'GpxMap'
}
</script>

<style scoped>
.map-gpx {
  width: 100%;
  height: 100%;
  background: #222;
}
</style> 